package br.unesp.rc.locadora.dao;

import br.unesp.rc.locadora.dao.connection.FabricaSessao;
import java.util.List;
import java.util.ArrayList;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

public abstract class BaseDAO<T> {
	
	public Class getGenericClass() {
		Class result = null;
		Type type = this.getClass().getGenericSuperclass();

		if(type instanceof ParameterizedType){
			ParameterizedType pt = (ParameterizedType) type;
			Type[] fieldArgTypes = pt.getActualTypeArguments();
			result = (Class) fieldArgTypes[0];
		}

		return result;
	}
	
	public boolean cadastrar(T entity) {
		boolean saved = false;
		
		Session session = FabricaSessao.getSessao();
		if (session != null) {
			Transaction t = session.beginTransaction();
			try{
				session.save(entity);
				t.commit();
				saved = true;
			} catch (HibernateException ex) {
				System.out.println("Problemas ao inserir: " + ex.getMessage());
				t.rollback();
            } finally{
                FabricaSessao.fechar(session);
            }
		}
		
		return saved;
	}
	
	public List<T> procurar(T entity) {
		List<T> list = new ArrayList<T>();
		Class genericClass = getGenericClass();
		
		Session session = FabricaSessao.getSessao();
		if (session != null) {
			Transaction t = session.beginTransaction();
			try{
				Criteria c = session.createCriteria(genericClass);
				list = c.list();
				t.commit();
			} catch (HibernateException ex) {
				System.out.println("Problemas ao procurar: " + ex.getMessage());
				t.rollback();
            } finally{
                FabricaSessao.fechar(session);
            }
		}
		
		return list;
	}
	
	public boolean atualizar(T entity) {
		boolean saved = false;
		
		Session session = FabricaSessao.getSessao();
		if (session != null) {
			Transaction t = session.beginTransaction();
			try{
				session.update(entity);
				t.commit();
				saved = true;
			} catch (HibernateException ex) {
				System.out.println("Problemas ao atualizar: " + ex.getMessage());
				t.rollback();
            } finally{
                FabricaSessao.fechar(session);
            }
		}
		
		return saved;
	}
	
	public boolean excluir(T entity) {
		boolean saved = false;
		
		Session session = FabricaSessao.getSessao();
		if (session != null) {
			Transaction t = session.beginTransaction();
			try{
				session.delete(entity);
				t.commit();
				saved = true;
			} catch (HibernateException ex) {
				System.out.println("Problemas ao deletar: " + ex.getMessage());
				t.rollback();
            } finally{
                FabricaSessao.fechar(session);
            }
		}
		
		return saved;
	}
}
